package org.apache.commons.graph.collections

import kotlin.jvm.JvmField

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * The [FibonacciHeap] node reference.
 *
 * @param <E> the type of elements held in the [FibonacciHeap] collection.
</E> */
internal class FibonacciHeapNode<E>(element: E) {
    /**
     * Returns the adapted element by this node.
     *
     * @return the adapted element by this node.
     */
    /**
     * The stored node value.
     */
    @JvmField
    val element: E

    /**
     * Returns the reference to the parent node, if any.
     *
     * @return the reference to the parent node, if any.
     */
    /**
     * Sets the reference to the parent node.
     *
     * @param parent the reference to the parent node
     */
    /**
     * Reference to the parent node, if any.
     */
    @JvmField
    var parent: FibonacciHeapNode<E>? = null

    /**
     * Returns the left node reference.
     *
     * @return the left node reference.
     */
    /**
     * Sets the left node reference.
     *
     * @param left the left node reference.
     */
    /**
     * `left[x]`.
     */
    @JvmField
    var left: FibonacciHeapNode<E> = this

    /**
     * Returns the right node reference.
     *
     * @return the right node reference.
     */
    /**
     * Sets the right node reference.
     *
     * @param left the right node reference.
     */
    /**
     * `right[x]`.
     */
    @JvmField
    var right: FibonacciHeapNode<E> = this

    /**
     * Returns the reference to the first child node.
     *
     * @return the reference to the first child node.
     */
    /**
     * Sets the reference to the first child node.
     *
     * @param child the reference to the first child node.
     */
    /**
     * Reference to the first child node.
     */
    @JvmField
    var child: FibonacciHeapNode<E>? = null

    /**
     * Returns the number of children in the child list of node `x` is stored in `degree[x]`.
     *
     * @return the number of children in the child list of node `x` is stored in `degree[x]`.
     */
    /**
     * The number of children in the child list of node `x` is stored in `degree[x]`.
     */
    var degree: Int = 0
        private set

    /**
     * Returns the current node mark status.
     *
     * @return true, if the node is marked, false otherwise.
     */
    /**
     * Flags the current node as marked.
     *
     * @param marked the current node mark status.
     */
    /**
     * `mark[x]` indicates whether node `x` has lost a child since
     * the last time `x` was made the child of another node.
     */
    var isMarked: Boolean = false

    /**
     * Build a new [FibonacciHeap] node with the given value.
     *
     * @param element the node value has to be stored.
     */
    init {
        // 1  degree[x] &larr; 0
        // 2  p[x] <- NIL
        parent = null
        // 3  child[x] <- NIL
        child = null
        // 4  left[x] <- x
        left = this
        // 5  right[x] <- x
        right = this
        // 6  mark[x] <- FALSE
        isMarked = false

        // set the adapted element
        this.element = element
    }

    /**
     * Decreases the degree of current node.
     *
     * @see .getDegree
     */
    fun decraeseDegree() {
        degree--
    }

    /**
     * Increases the degree of current node.
     *
     * @see .getDegree
     */
    fun incraeseDegree() {
        degree++
    }

    /**
     * {@inheritDoc}
     */
    override fun toString(): String {
        return element.toString()
    }

    fun setParentNode(e: FibonacciHeapNode<E>?) {
       parent = e
    }

    fun setRightNode(right: FibonacciHeapNode<E>) {
        this.right=right
    }

    fun setLeftNode(left: FibonacciHeapNode<E>) {
        this.left=left
    }

    fun setChildNode(y: FibonacciHeapNode<E>?) {
       this.child=y
    }
}
